package com.itheima.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.pojo.*;
import com.itheima.service.EmpService;
import com.itheima.service.EmproleService;
import com.itheima.service.PermissionService;
import com.itheima.service.RolePermissionService;
import com.itheima.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.beans.BeanProperty;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@RestController
public class LoginController {

    @Autowired
    private EmpService empService;

    @Autowired
    private RolePermissionService rolePermissionService;

    @Autowired
    private PermissionService permissionService;
    @Autowired
    private EmproleService emproleService;
    @RequestMapping(value = "/checkCode")  // 映射到请求路径 "/checkCode"
    public void checkCode(HttpServletResponse response, HttpSession session, Integer type) throws IOException {
        // 创建验证码生成工具，参数为宽度100、高度38、4个字符和字符长度为10
        CreateImageCode vCode = new CreateImageCode(100, 38, 4, 10);

        // 设置响应头，确保浏览器不会缓存验证码图片
        response.setHeader("Pragma", "no-cache");  // 避免旧验证码被缓存
        response.setHeader("Cache-Control", "no-cache");  // 防止浏览器缓存
        response.setDateHeader("Expires", 0);  // 设置过期时间为0，防止缓存
        response.setContentType("image/jpeg");  // 设置响应内容类型为图片格式（JPEG）

        // 获取生成的验证码文本
        String code = vCode.getCode();

        // 如果没有传入type参数或type为0，则将验证码保存到session中
        if (type == null || type == 0) {
            session.setAttribute(Constants.CHECK_CODE_KEY, code);  // 保存验证码到session
        }

        // 将生成的验证码图片写入响应流，返回给前端
        vCode.write(response.getOutputStream());
    }

    @RequestMapping(value = "/verifyCode", method = RequestMethod.POST)  // 映射到请求路径 "/verifyCode"，POST请求
    @ResponseBody  // 该方法返回布尔值，直接写入响应体
    public boolean verifyCode(@RequestBody VerifyCodeRequest request, HttpSession session, Integer type) {
        // 从请求体中获取传递的验证码（imageCode）
        String imageCode = request.getImageCode();  // 获取请求体中的imageCode

        // 打印接收到的验证码，方便调试
        System.out.println("接收到的验证码: " + imageCode);

        // 获取session中存储的验证码
        String storedCode = null;

        // 判断类型，如果为null或0，获取默认验证码
        if (type == null || type == 0) {
            storedCode = (String) session.getAttribute(Constants.CHECK_CODE_KEY);  // 从session中获取默认验证码
        }

        // 如果session中没有验证码，则验证失败，返回false
        if (storedCode == null) {
            return false;  // 如果session中没有存储验证码，返回false
        }

        // 比较传入的验证码和session中保存的验证码，忽略大小写
        return storedCode.equalsIgnoreCase(imageCode);  // 如果两者相同，返回true，否则返回false
    }


    @PostMapping("/login")
    public Result login(@RequestBody Emp emp) {
        log.info("员工登录: {}", emp);  // 记录日志，输出登录的员工信息

        Emp e = empService.login(emp);  // 调用登录服务，验证员工信息
        EmpDTO empDTO = new EmpDTO();  // 创建EmpDTO对象，用于存储返回的数据


        LambdaQueryWrapper<Permission> permissionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<RolePermission> rolePermissionLambdaQueryWrapper = new LambdaQueryWrapper<>();

// 获取完整权限映射
        Map<Integer, String> permissionMap = permissionService.list(permissionLambdaQueryWrapper)
                .stream()
                .collect(Collectors.toMap(Permission::getId, Permission::getCode, (oldValue, newValue) -> oldValue));

        List<String> userPermissions = new ArrayList<>();
        // 判断员工登录是否成功
        if (e != null) {
            // 查询员工对应的角色（假设存在员工-角色关联表）
            List<Integer> roleIds = emproleService.listRoleIdsByEmployeeId(e.getId());
            log.info("Role IDs: {}", roleIds);
            // 查询角色对应的权限
            List<Integer> permissionIds = rolePermissionService.listPermissionIdsByRoleIds(roleIds);
            log.info("Permission IDs: {}", permissionIds);
            // 批量转换权限代码
            userPermissions = permissionIds.stream()
                    .map(permissionMap::get)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            String jwt = JwtUtils.generateJwt(Map.of(
                            "id", e.getId(),
                            "username", e.getUsername(),
                            "menus", userPermissions
                    ));
            empDTO.setJWT(jwt);
            empDTO.setEmp(e);
            empDTO.setMenus(userPermissions);
            empDTO.setRoleIds(roleIds);
            return Result.success(empDTO);
        }
        return Result.error("用户名或密码错误");
    }

    @PostMapping("/register")
    public Result register(@RequestBody Emp emp) {
        log.info("员工注册: {}", emp);  // 记录日志，输出登录的员工信息
        Emp e = empService.register(emp);  // 调用注册服务，验证员工信息
        // 如果注册失败（例如手机号已存在），返回相应的错误信息
        if (e == null) {
            return Result.error("手机号已存在");  // 返回失败的Result
        }
        // 注册成功，返回成功信息和用户信息
        return Result.success(e);  // 返回成功的Result
    }
}
